package com.lc.fbtp.draftmsg.core.parse;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.Unmarshaller.Listener;

import org.apache.commons.lang3.StringUtils;

import com.lc.fbtp.draftmsg.core.parse.exception.IllegalMessageException;

public class JaxbBinder {

	private JAXBContext jaxbContext;

	public JaxbBinder(Class<?>... types) {
		try {
			jaxbContext = JAXBContext.newInstance(types);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}
	
	public String toXML(Object object){
		return toXML(object, "UTF-8");
	}
	
	public String toXML(Object object,String encoding){
		try {
            StringWriter writer = new StringWriter();
            Marshaller marshaller = createMarshaller(encoding);
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
            marshaller.marshal(object, writer);
            return writer.toString();
        } catch (JAXBException e) {
            throw new IllegalMessageException("对象转XML失败");
        }
	}
	
	@SuppressWarnings("unchecked")
	public <T> T fromXML(InputStream stream) {
        try {
            Unmarshaller unmarshaller = createUnmarshaller();
            return (T) unmarshaller.unmarshal(stream);
        } catch (JAXBException e) {
            throw new IllegalMessageException(e);
        }
    }
	
	@SuppressWarnings("unchecked")
	public <T> T fromXML(String xml) throws IllegalMessageException {
	    try {
	        StringReader reader = new StringReader(xml);
	        return (T) createUnmarshaller().unmarshal(reader);
	    } catch (JAXBException e) {
	    	e.printStackTrace();
	        throw new IllegalMessageException("XML转对象失败");
	    }
	}
	
	@SuppressWarnings("unchecked")
	public <T> T fromXML(String xml,Listener listener) {
	    try {
	        StringReader reader = new StringReader(xml);
	        Unmarshaller unmarshaller = createUnmarshaller();
	        unmarshaller.setListener(listener);
	        return (T) unmarshaller.unmarshal(reader);
	    } catch (JAXBException e) {
	    	e.printStackTrace();
	        throw new IllegalMessageException("XML转对象失败");
	    }
	}
	
	  /**
     * 创建Marshaller, 设定encoding(可为Null).
     */
    private Marshaller createMarshaller(String encoding) {
        try {
            Marshaller marshaller = jaxbContext.createMarshaller();
 
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 
            if (StringUtils.isNotBlank(encoding)) {
                marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            }
            return marshaller;
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
	
    /**
     * 创建UnMarshaller.
     */
    private Unmarshaller createUnmarshaller() {
        try {
            return jaxbContext.createUnmarshaller();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
}
